<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="icon" href="./static/favicon.ico">
  <title>xDevice Report</title>
  <link rel="stylesheet" href="static/css/element-plus@2.3.4_index.css">
  <link rel="stylesheet" href="static/css/index.css">
  <script src="static/vue@3.2.41_global.min.js"></script>
  <script src="static/element-plus@2.3.4_index.full.js"></script>
  <script src="static/element-plus_icons-vue@2.0.10_index.iife.min.js"></script>
  <script src="static/EventEmitter.js"></script>
  <script src="static/components/popoverCheckBox.js"></script>
  <script src="static/data.js"></script>
</head>

<body>

  <div id="app">
    <div class="container">
      <div class="summary" v-if="summary">
        <el-descriptions title="Summary" :column="3" border>
          <el-descriptions-item label="Test Start">{{
            summary.test_start
            }}</el-descriptions-item>
          <el-descriptions-item label="Test End">{{
            summary.test_end
            }}</el-descriptions-item>
          <el-descriptions-item label="Elapsed">{{
            summary.execute_time
            }}</el-descriptions-item>
          <el-descriptions-item label="Test Type">{{
            summary.test_type
            }}</el-descriptions-item>
          <el-descriptions-item label="Host Info" span="2">{{
            summary.host_info
            }}</el-descriptions-item>
          <el-descriptions-item label="Logs">
            <div>
              <el-link v-for="(item, index) in summary.logs" :key="index" :href="item" target="_blank" type="primary">
                {{ index }}
                <span
                  v-if="index !== Object.keys(summary.logs)[Object.keys(summary.logs).length - 1]">&nbsp;&nbsp;</span>
              </el-link>
            </div>
          </el-descriptions-item>
        </el-descriptions>
      </div>
      <div class="statistic" v-if="statistics">
        <el-row :gutter="10" class="row-statistic">
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic value="Modules" :title="statistics.modules"></el-statistic>
          </el-col>
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic value="Repeat" :title="statistics.repeat"></el-statistic>
          </el-col>
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic class="success" value="Run Modules" :title="statistics.runmodules"></el-statistic>
          </el-col>
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic value="Total Tests" :title="statistics.tests"></el-statistic>
          </el-col>
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic class="success" value="Passed" :title="statistics.passed"></el-statistic>
          </el-col>
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic class="error" value="Failed" :title="statistics.failed"></el-statistic>
          </el-col>
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic class="blocked" value="Blocked" :title="statistics.blocked"></el-statistic>
          </el-col>
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic value="Ignored" :title="statistics.ignored"></el-statistic>
          </el-col>
          <el-col :span="2" style="width: 11.11%;">
            <el-statistic value="Unavailable" :title="statistics.unavailable"></el-statistic>
          </el-col>
        </el-row>
      </div>
      <div class="list" v-if="devicesList && devicesList.length > 0">
        <p>Test Devices</p>
        <el-table :data="devicesList" style="width: 100%" ref="table" :max-height="maxHeight">
          <el-table-column type="index" label="#" min-width="3%"></el-table-column>
          <el-table-column prop="sn" label="SN" min-width="22%" show-overflow-tooltip="">
            <template #default="scope">
              <span>{{scope.row.sn ? scope.row.sn : '-'}}</span>
            </template> </el-table-column>
          <el-table-column prop="model" label="Model" min-width="14%">
            <template #default="scope">
              <span>{{scope.row.model ? scope.row.model : '-'}}</span>
            </template> </el-table-column>
          <el-table-column prop="type" label="Type" min-width="14%">
            <template #default="scope">
              <span>{{scope.row.type ? scope.row.type : '-'}}</span>
            </template> </el-table-column>
          <el-table-column prop="platform" label="Platform" min-width="14%">
            <template #default="scope">
              <span>{{scope.row.platform ? scope.row.platform : '-'}}</span>
            </template>
          </el-table-column>
          <el-table-column prop="version" label="Version" min-width="16%">
            <template #default="scope">
              <span>{{scope.row.version ? scope.row.version : '-'}}</span>
            </template>
          </el-table-column>
          <el-table-column prop="others" label="Others" min-width="17%">
            <template #default="scope">
              <div v-if="scope.row.others && Object.keys(scope.row.others).length !== 0">
                <span class="div-others div-error">{{scope.row.others}}</span>
                <el-tooltip class="box-item" effect="dark" content="查看" placement="top">
                  <span class="span-img"><img class="img" src="static/view.svg" alt=""
                      @click="changeShowDetails(scope.row)"></span>

                </el-tooltip>
                <el-tooltip class="box-item" effect="dark" content="复制" placement="top">
                  <span class="span-img">
                    <img class="img" src="static/copy.svg" alt="" @click="copyOldData(scope.row.others)"></span>

                </el-tooltip>
              </div>
              <span v-else>-</span>
              <el-dialog v-model="scope.row.showDetails" width="60%" append-to-body>
                <div class="div-dialog">
                  <el-descriptions class="des-style" :column="2" border>
                    <el-descriptions-item v-for="(item,index) in scope.row.others" :key="index" :label="index">{{
                      item
                      }}</el-descriptions-item>
                  </el-descriptions>
                </div>
              </el-dialog>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="list">
        <p>Test Details</p>
        <el-table :data="list" style="width: 100%" border @sort-change="handleSortChange" class="details-table">
          <el-table-column type="index" label="#" min-width="3%"></el-table-column>
          <el-table-column show-overflow-tooltip="" min-width="22%" resizable>
            <template #header>
              <popover-checkbox headername="Module" :options="options" @change="handFilterChange">
              </popover-checkbox>
            </template>
            <template #default="scope">
              <el-link type="primary" @click="viewDetail(scope.row)">{{
                scope.row.name
                }}</el-link>
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip="" resizable min-width="7%">
            <template #header>
              <popover-checkbox headername="Round" :options="roundOptions" @change="handRoundChange">
              </popover-checkbox>
            </template>
            <template #default="scope">
              <span>{{
                scope.row.round
                }}</span>
            </template>
          </el-table-column>
          <el-table-column sortable prop="time" label="Time(s)" min-width="7%"> </el-table-column>
          <el-table-column sortable prop="tests" label="Tests" min-width="7%"> </el-table-column>
          <el-table-column sortable prop="passed" label="Passed" min-width="7%"> </el-table-column>
          <el-table-column sortable prop="failed" label="Failed" min-width="7%">
            <template #default="scope">
              <span :class="[scope.row.failed > 0 ? 'table-error':'']">{{ scope.row.failed }}</span>
            </template>
          </el-table-column>
          <el-table-column sortable prop="blocked" label="Blocked" min-width="7%">
            <template #default="scope">
              <span :class="[scope.row.blocked > 0 ? 'table-blocked':'']">{{ scope.row.blocked }}</span>
            </template>
          </el-table-column>
          <el-table-column sortable prop="ignored" label="Ignored" min-width="7%"> </el-table-column>
          <el-table-column sortable prop="passingrate" label="Passing Rate" min-width="9%">
            <template #default="scope">
              <el-progress :text-inside="true" :stroke-width="22" precision="2" status="success"
                :percentage="scope.row.passingrate" :color="customColorMethod(scope.row.passingrate)" />
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip prop="error" label="Error" min-width="17%">
            <template #header>
              <popover-checkbox headername="Error" :options="errorOptions" @change="handErrorChange">
              </popover-checkbox>
            </template>
            <template #default="scope">
              <span>{{
                scope.row.error
                }}</span>
            </template>
          </el-table-column>
        </el-table>
        <div class="pager">
          <el-pagination background v-bind="paginationInfo" @current-change="handlePageChange"
            @size-change="handleSizeChange" />
        </div>
      </div>

    </div>
  </div>

  <script>
    const { createApp, ref, reactive } = Vue
    const app = createApp({
      setup() {
        const summary = ref();
        const maxHeight = ref('0px');
        const keyword = reactive([]);
        const options = reactive([]);
        const roundKeyword = reactive([]);
        const roundOptions = reactive([]);
        const errorKeyword = reactive([]);
        const errorOptions = reactive([]);
        const statistics = ref();
        const totalList = [];
        const list = ref([]);
        const deviceslist = ref([]);
        const paginationInfo = reactive({
          layout: "total, sizes, prev, pager, next, jumper",
          total: 0,
          pageSize: 10,
          currentPage: 1,
          pageSizes: [10, 20, 50],
        });

        return {
          keyword,
          roundKeyword,
          options,
          roundOptions,
          errorKeyword,
          errorOptions,
          summary,
          statistics,
          totalList,
          list,
          paginationInfo,
          deviceslist,
          maxHeight,
        }
      },
      mounted() {
        this.initData()
        setTimeout(() => {
          let headHeight = 0;
          let firstRowHeight = 0;
          let secondRowHeight = 0;
          if (this.devicesList && this.devicesList.length > 0) {
            if (this.devicesList.length > 1) {
              secondRowHeight = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody tr:nth-child(2)').clientHeight;
            }
            firstRowHeight = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody tr:first-child').clientHeight;
            headHeight = this.$refs.table.$el.querySelector('.el-table__header-wrapper thead tr:first-child').clientHeight;
          }
          const maxTableHeight = headHeight + firstRowHeight + secondRowHeight;
          this.maxHeight = maxTableHeight + 'px';
        }, 0);
      },
      methods: {
        customColorMethod(percentage) {
          if (percentage < 50) {
            return 'red'
          }
          if (percentage < 100) {
            return '#ffb400'
          }
          return '#67c23a'
        },
        handleSortChange({ column, prop, order }) {
          if (column && prop && order) {
            this.totalList.sort((a, b) => {
              const valueA = a[prop];
              const valueB = b[prop];
              if (order === 'ascending') {
                return valueA > valueB ? 1 : -1;
              } else if (order === 'descending') {
                return valueA < valueB ? 1 : -1;
              }
              return 0;
            });
          }
          this.paginationInfo.currentPage = 1;
          this.getPageData();
        },
        getPageData() {
          this.list.length = 0;
          const { pageSize, currentPage } = this.paginationInfo;
          const startIndex = (currentPage - 1) * pageSize;
          const endIndex = startIndex + pageSize;
          let filterData = [...this.totalList];
          if (this.keyword.length) {
            filterData = this.totalList.filter((item) => this.keyword.includes(item.name));
          }
          if (this.roundKeyword.length) {
            filterData = this.totalList.filter((item) => this.roundKeyword.includes(item.round));
          }
          if (this.errorKeyword.length) {
            filterData = this.totalList.filter((item) => this.errorKeyword.includes(item.error));
          }
          const pageData = filterData.slice(startIndex, endIndex);
          this.list.push(...pageData);
        },
        initData() {
          const { modules, exec_info, summary, devices } = window.reportData;
          this.devicesList = devices;
          modules.forEach((item) => {
            const { tests, blocked, failed, ignored, passed, time, passingrate } = item;
            item.blocked = new Number(blocked);
            item.failed = new Number(failed);
            item.ignored = new Number(ignored);
            item.passed = new Number(passed);
            item.tests = new Number(tests);
            item.time = new Number(time);
            item.passingrate = parseFloat(passingrate.replace('%', ''));
          });

          this.totalList = modules.map(item => {
            return {
              name: item.name, round: item.round, time: item.time, tests: item.tests, failed: item.failed, ignored: item.ignored,
              passed: item.passed, blocked: item.blocked, passingrate: item.passingrate, report: item.report, error: item.error
            }
          });

          this.paginationInfo.total = this.totalList.length;
          this.getPageData();
          this.summary = exec_info;
          for (const key in summary) {
            if (summary[key] !== '') {
              summary[key] = new Number(summary[key]);
            }
          }
          this.statistics = summary;

          const nameList = modules.map((item) => item.name);
          this.options.push(...new Set(nameList));
          const roundList = modules.map((item) => item.round);
          this.roundOptions.push(...new Set(roundList));
          const errorList = modules.map((item) => item.error);
          this.errorOptions.push(...new Set(errorList));
        },
        handFilterChange(val) {
          this.keyword.length = 0;
          this.paginationInfo.currentPage = 1;
          this.keyword.push(...val);
          this.getPageData();
        },
        handRoundChange(val) {
          this.roundKeyword.length = 0;
          this.paginationInfo.currentPage = 1;
          this.roundKeyword.push(...val);
          this.getPageData();
        },
        handErrorChange(val) {
          this.errorKeyword.length = 0;
          this.paginationInfo.currentPage = 1;
          this.errorKeyword.push(...val);
          this.getPageData();
        },
        viewDetail(data) {
          const { name, report, round } = data;
          if (report) {
            window.open(`${report}`);
          } else {
            window.open(`./static/detail.html?name=${name}&round=${round}`, "_blank");
          }
        },
        handlePageChange(pageNum) {
          this.paginationInfo.currentPage = pageNum;
          this.getPageData();
        },
        handleSizeChange(size) {
          this.paginationInfo.currentPage = 1;
          this.paginationInfo.pageSize = size;
          this.getPageData();
        },
        changeShowDetails(row) {
          row.showDetails = true;
        },
        copyOldData(value) {
          if (navigator.clipboard) {
            navigator.clipboard.writeText(JSON.stringify(value)).then(() => {
              ElementPlus.ElMessage({
                message: '复制成功',
                type: 'success',
              })
            }).catch(() => {
              ElementPlus.ElMessage.error('复制失败')
            })
          } else {
            const textarea = document.createElement('textarea');
            textarea.value = JSON.stringify(value);
            document.body.appendChild(textarea);
            textarea.select();
            try {
              const successful = document.execCommand('copy');
              successful ? ElementPlus.ElMessage({
                message: '复制成功',
                type: 'success',
              }) : ElementPlus.ElMessage.error('复制失败')
            } catch (err) {
              ElementPlus.ElMessage.error('复制失败')
            }
            document.body.removeChild(textarea)
          }
        }
      },
    })
    app.component(popoverCheckBox.name, popoverCheckBox.component);
    app.component("ArrowDown", ElementPlusIconsVue.ArrowDown)
    app.use(ElementPlus)
    app.mount('#app')

  </script>
</body>

</html>